/*
 * Copyright (c) 2025 Li Auto Inc. and its affiliates
 * Licensed under the Apache License, Version 2.0(the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include <stddef.h>

#define IPICALL_IRQ 0

typedef void (*ipicall_func_t)(void);

/*TODO: this varible should be mapped to none cache area,when cache is enabled*/

static void *ipicall_callback[CONFIG_RT_FRAMEWORK_NCORES] __attribute__((__align(32))) = { NULL };

void up_ipicall_isr_handler(void *arg)
{
	(void)arg;
	unsigned char cpu = (unsigned char)up_cpu_index();

	if (ipicall_callback[cpu] != NULL) {
		((ipicall_func_t)(ipicall_callback[cpu]))();
	}
}

void up_ipicall_attach(void *handler)
{
	ipicall_callback[up_cpu_index()] = handler;
}

int up_trigger_ipicall(unsigned int cpu)
{
	int ret = -1;

	if (cpu < CONFIG_RT_FRAMEWORK_NCORES) {
		up_trigger_irq(IPICALL_IRQ, (1 << cpu));
		ret = 0;
	}

	return ret;
}

void up_trigger_ipicalls(unsigned int cpu_mask)
{
	up_trigger_irq(IPICALL_IRQ, cpu_mask);
}
